package org.jeecg.modules.zhima.portal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.modules.zhima.base.common.Constant.RedisKey;
import org.jeecg.modules.zhima.base.common.ResultCode;
import org.jeecg.modules.zhima.base.exception.Asserts;
import org.jeecg.modules.zhima.base.shiro.service.TokenService;
import org.jeecg.modules.zhima.base.util.RedisKeyUtil;
import org.jeecg.modules.zhima.base.util.RedisUtil;
import org.jeecg.modules.zhima.center.entity.UmsMember;
import org.jeecg.modules.zhima.center.service.IUmsFootprintService;
import org.jeecg.modules.zhima.center.service.IUmsMemberService;
import org.jeecg.modules.zhima.center.service.IUmsProductCollectService;
import org.jeecg.modules.zhima.portal.domain.LoginInfo;
import org.jeecg.modules.zhima.portal.domain.MemberDetails;
import org.jeecg.modules.zhima.portal.domain.WXMemberDetails;
import org.jeecg.modules.zhima.portal.domain.UmsUserInfo;
import org.jeecg.modules.zhima.portal.service.ICouponService;
import org.jeecg.modules.zhima.portal.service.IPlayerService;
import org.jeecg.modules.zhima.portal.service.IUmsMemberCacheService;
import org.jeecg.modules.zhima.portal.service.IUserService;
import org.jeecg.modules.zhima.portal.util.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUmsMemberService memberService;
    @Autowired
    private IUmsMemberCacheService memberCacheService;
    @Autowired
    private IUmsProductCollectService productCollectService;
    @Autowired
    private IUmsFootprintService footprintService;
    @Autowired
    private ICouponService couponService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private IPlayerService playerService;

    @Override
    public WXMemberDetails getUserDetails() {
        return new WXMemberDetails(this.getCurrentMember());
    }

    @Override
    public WXMemberDetails getUserById(Integer memberId) {
        return new WXMemberDetails(memberService.getById(memberId));
    }

    @Override
    public WXMemberDetails getUserDetails(String wxOpenId) {
        UmsMember umsMember = this.getMemberByWxOpenId(wxOpenId);
        return new WXMemberDetails(umsMember);
    }

    @Override
    public UmsMember getMemberByWxOpenId(String wxOpenId) {
        String key = redisUtil.getKeyWithColumn(RedisKeyUtil.MEMBER_INFO, wxOpenId);
        if (redisUtil.hasKey(key)){
            return (UmsMember)redisUtil.get(key);
        }
        UmsMember umsMember = memberService.getByWeXinOpenId(wxOpenId);
        redisUtil.set(key, umsMember);
        return umsMember;
    }

    @Override
    public UmsMember getMemberByPhone(String phone) {
        String key = redisUtil.getKeyWithColumn(RedisKeyUtil.MEMBER_INFO, phone);
        if (redisUtil.hasKey(key)){
            return (UmsMember)redisUtil.get(key);
        }
        UmsMember umsMember = memberService.getByPhone(phone);
        redisUtil.set(key, umsMember);
        return umsMember;
    }

    @Override
    public UmsMember getCurrentMember() {
        SecurityContext ctx = SecurityContextHolder.getContext();
        Authentication auth = ctx.getAuthentication();
        Object principal = auth.getPrincipal();
        if (principal instanceof WXMemberDetails){
            WXMemberDetails memberDetails = (WXMemberDetails) principal;
            return memberDetails.getUmsMember();
        }
        return null;
    }

    @Override
    public WXMemberDetails loginOrRegisterUser(UmsMember umsMember, String invitationCode) {
        UmsMember umsMember1 = this.getMemberByWxOpenId(umsMember.getWeixinOpenid());
        if (null == umsMember1) {
            if (StringUtils.isNotEmpty(invitationCode)){
//                UmsMember invitor = memberService.getByInvitationCode(invitationCode);
                UmsMember invitor = memberService.getById(invitationCode);
                if (invitor != null){
                    umsMember.setParentUserId(invitor.getId());
                }
            }
            umsMember.setInvitationCode(UUID.randomUUID().toString().replaceAll("-","").toUpperCase());
            umsMember.setCreateTime(new Date());
            memberService.save(umsMember);
            return new WXMemberDetails(umsMember);
        }
        return new WXMemberDetails(umsMember1);
    }

    @Override
    public LoginUser getUserByName(String username) {
        return null;
    }

    @Override
    public LoginInfo loginAndRegist(String phone, String pwd) {
        LoginInfo loginInfo = new LoginInfo();
        UmsMember umsMember = this.getMemberByPhone(phone);
        if (umsMember == null){
            umsMember = memberService.getOne(new LambdaQueryWrapper<UmsMember>().eq(UmsMember::getPhone, phone));
        }
        if (umsMember == null){
            umsMember = new UmsMember();
            umsMember.setNickname(phone);
            umsMember.setPhone(phone);
            umsMember.setPassword(pwd);
            umsMember.setCreateTime(new Date());
            umsMember.setStatus(1);
            memberService.save(umsMember);
        }else if (!pwd.equals(umsMember.getPassword())){
            Asserts.fail("账号密码错误");
        }
        loginInfo.setUserInfo(umsMember);
        MemberDetails memberDetails = new MemberDetails(umsMember);
//        loginInfo.setToken(jwtTokenUtil.generateToken(memberDetails));
        loginInfo.setToken(tokenService.createToken(umsMember.getPhone(), umsMember.getId(), umsMember.getPassword(), TokenService.EXPIRATION));
//        redisUtil.set(loginInfo.getToken(), memberDetails);
        String loginUserKey = RedisKey.getLoginUserKey(phone);
        redisUtil.set(loginUserKey, umsMember);
        return loginInfo;
    }

    @Override
    public LoginInfo loginByPassword(String phone, String pwd) {
        LoginInfo loginInfo = new LoginInfo();
        UmsMember umsMember = this.getMemberByPhone(phone);
        if (umsMember == null){
            umsMember = memberService.getOne(new LambdaQueryWrapper<UmsMember>().eq(UmsMember::getPhone, phone));
        }
        if (umsMember == null){
            Asserts.fail(ResultCode.USERNAME_NOT_EXIST);
        }else if (!pwd.equals(umsMember.getPassword())){
            Asserts.fail("账号密码错误");
        }
        loginInfo.setUserInfo(umsMember);
        loginInfo.setPlayer(playerService.getOrAdd(umsMember.getId()+""));
        MemberDetails memberDetails = new MemberDetails(umsMember);
//        loginInfo.setToken(jwtTokenUtil.generateToken(memberDetails));
        loginInfo.setToken(tokenService.createToken(umsMember.getPhone(), umsMember.getId(), umsMember.getPassword(), 10000000l));
        redisUtil.set(loginInfo.getToken(), memberDetails);
        return loginInfo;
    }

    @Override
    public void updateIntegration(Integer id, Integer integration) {
        memberService.updateIntegration(id, integration);
        memberCacheService.delMember(id);
    }

    @Override
    public UmsUserInfo getUmsUserInfo(Integer memberId) {
        UmsUserInfo info = new UmsUserInfo();
        info.setCollectNum(productCollectService.countByUserId(memberId));
        info.setFootNum(footprintService.countByUserId(memberId));
        info.setCouponNum(couponService.countByMemberId(memberId));
        return info;
    }

    @Override
    public boolean updateById(UmsMember member) {
        return memberService.updateById(member);
    }
}
